'use strict';
const db = uniCloud.database();
const dbCmd = db.command
const $ = db.command.aggregate
const tools = require("../../tools/index.js")
const alioss = require('../../oss/index.js')
const Encryption_decryption = require('../../JSEncrypt/index.js')

// 登录接口（admin用户）
exports.Login = async function(body_data) {
	let {account,pwd} = body_data;
	if (!account) {return {code:200,msg: "参数错误"}};
	// 解密
	account = Encryption_decryption.$JSEncrypt.decrypt(account);
	pwd = Encryption_decryption.$JSEncrypt.decrypt(pwd);
	
	try {
		const affair = await db.runTransaction(async transaction => {
			let Token = tools.create_token(); // 生成一个token
			// 查询账号是否注册过
			let res = await transaction.collection('admin-User').where({account}).get()
			if (res.data.length===0) {return {code: 204,msg: "该账户未注册过"}}
			if (res.data[0].pwd !== pwd) {return {code: 204,msg: "账号密码错误"}}
			await transaction.collection('admin-User').where({account}).update({Token})
			// 数据存在
			let Sts = await alioss.assumeRole()
			return {
				code: 200,
				msg: '登录成功~',
				Token,
				Sts
			}
		})
		return affair
	}catch(e){
		console.error(`事务失败`, e)
		return {
			msg: '内部错误~',
			code: 500
		}
	}
}

// 注册接口（admin用户）
exports.Register = async function(body_data) {
	let {
		account,pwd,role,avatar,sex,Nickname,birth,introduce
	} = body_data, addJson = {};
	
	if (!account) {return {code:200,msg: "参数错误"}};
	// 解密
	// account = Encryption_decryption.$JSEncrypt.decrypt(account);
	// pwd = Encryption_decryption.$JSEncrypt.decrypt(pwd);
	
	
	try {
		/* 处理参数操作 */
		let celue = ['account','pwd','role','avatar', 'sex', 'Nickname', 'birth', 'Region', 'introduce']
		for (let i = 0, item; item = celue[i]; i++) {
			body_data[item]? addJson[item] = body_data[item] :""
		}
		
		const affair = await db.runTransaction(async transaction => {
			// 查询账号是否注册过
			let res = await transaction.collection('admin-User').where({account}).get()
			if (res.data.length>0) {return {code: 204,msg: "该账户已经注册"}}
			let AddRes = await transaction.collection('admin-User').add(Object.assign(addJson,{
				registerTime: new Date(),
				Token: null,
			}))
			if(AddRes.id){
				let Sts = await alioss.assumeRole()
				return {
					code: 200,
					msg: '注册成功~',
					Sts
				}
			}else{
				await transaction.rollback('注册未成功~')
			}
		})
		return affair
	}catch(e){
		console.error(`事务失败`, e)
		return {
			msg: '内部错误~',
			code: 500
		}
	}
}

// 删除用户接口（admin用户）
exports.admin_DelUser = async function(body_data) {
	let {UserInfo,_id} = body_data
	if (!_id.toString()) {return {msg: "_id必传"}}
	
	try {
		const result = await db.runTransaction(async transaction => {
			let SelRes = await transaction.collection('admin-User').doc(_id).get()
			if (SelRes.data) {
				try {
					let ossRes = null
					let DelRes = await db.collection('admin-User').doc(_id).remove()		// 删除用户信息
					if(DelRes.deleted>0){
					// 	ossRes = await digui_del(SelRes.data.account+'/')		// 删除oss的数据 （app端的文件数据）
					// 	if(ossRes===200){
							ossRes = await digui_del('uploadImg/'+SelRes.data.account+'/')		// 删除oss的数据（uploadImg下该用户的所有信息）
					// 	}
					}
					console.log(`事务全部成功~`)
					return{
						ossRes,
						DelRes
					}
				} catch (e) {
					await transaction.rollback('oss,remove')
				}
			} else {
				await transaction.rollback('查询User')
			}
		})
	
		return {
			code:200,
			msg:'删除成功~',
			data:{
				ossRes:result.ossRes,
				DelRes:result.DelRes
			}
		}
	} catch (e) {
		console.error(`事务失败`,e)
		return {
			msg:'内部错误~',
			code:500
		}
	}
}

// 更新用户信息（admin用户）
exports.admin_UpdlUser = async function(body_data) {
	let res = {
		code:200,
		msg:"成功~"
	}
	let {_id,pwd,role,Nickname,birth,sex,introduce,avatar} = body_data
	if (!_id.toString()) {return {msg: "_id必传"}}
	
	let UpdJson = {}
	let celue = ['pwd','role','avatar', 'sex', 'Nickname', 'birth', 'introduce']
	for (let i = 0, item; item = celue[i]; i++) {
		body_data[item]? UpdJson[item] = body_data[item] :""
	}
	
	let result = await db.collection('admin-User').doc(_id).update(UpdJson)
	if(result.requestId){
		res.msg='更新成功~'
		res.data=result.data
	}else{
		res.msg='内部错误~'
		res.code=500
	}
	return res
}

// 获取用户信息接口（admin用户）
exports.GetUserInfo = async function(body_data) {
	let {Token} = body_data
	try{
		let res = await db.collection('admin-User').aggregate().match({Token}).limit(1).lookup({
			from: 'admin-role',
			localField: 'role',
			foreignField: 'RoleName',
			as: "RouterList"
		}).unwind('$RouterList').end()
		// let res = await db.collection('admin-User').where({Token}).get()
		if(res.data.length>0){
			return {
				msg: "获取个人信息成功~",
				code: 200,
				result: res.data[0]
			}
		}else{
			return {
				msg: "身份已过期,请重新登录~",
				code: 204,
			}
		}
	}catch(e){
		return {
			code:500,
			msg:'内部错误~'
		}
	}
}

// 获取临时Sts权限接口（admin用户）
exports.GetSts = async function(body_data) {
	let {expiration} = body_data
	let Sts = await alioss.assumeRole(expiration.toString())
	return {
		code:200,
		msg:"获取成功~",
		Sts
	}
}

// 获取用户列表接口（admin用户的）
exports.admin_SelUserList = async function(body_data) {
	return SelUserList(body_data,'admin-User')
}

// 获取用户列表接口 (洋盘用户的)
const SelUserList = async function(body_data,collectionType='User') {
	let res = { code:200, msg:"成功~" }
	// 	结构前端传的参数
	let { 	UserInfo,Nickname,account,Region,birth,sex,introduce,registerTime,pageNum,pageSize,
		birthBeginTime,birthEndTime,registerTimeBeginTime,registerTimeEndTime } = body_data
	//  接口参数限制
	if (!pageNum.toString() || !pageSize) {return {msg: "pageNum/pageSize必传"}}
	if ( (registerTimeBeginTime && !registerTimeEndTime) || (!registerTimeBeginTime && registerTimeEndTime) ) {return {msg: "日期必须选择范围"}}
	
	
	let Skips = pageNum * pageSize
	/******	处理参数为空的数据 不传给数据库	******/
	let SelJson = {}
	let celue = ['Region','birth','sex','introduce','registerTime',
		'birthBeginTime','birthEndTime']
	for(let i in celue){ 	body_data[celue[i]]  ? SelJson[celue[i]]= body_data[celue[i]] :""  }
	
	
	/*****	处理参数的模糊查询	******/
	let like_Json = {}
	let like_celue = ['Nickname','account','Region']
	for(let i in like_celue){ 	 body_data[like_celue[i]] ? like_Json[like_celue[i]] =  new RegExp(`${body_data[like_celue[i]]}`) :"" 	}
	
	/*****	处理参数的日期查询范围	******/
	registerTimeBeginTime && registerTimeEndTime ?  like_Json['registerTime'] = dbCmd.and([
	  dbCmd.gte(new Date(registerTimeBeginTime)),
	  dbCmd.lte(new Date(registerTimeEndTime))
	]) :""
	
	
	let Total = await db.collection(collectionType).where(Object.assign(SelJson,like_Json)).count()
	let result = await db.collection(collectionType).where( Object.assign(SelJson,like_Json) ).limit(pageSize).skip(Skips).get()
	if(result.requestId){
		res.msg='查询成功~'
		res.data=result.data
		res.total = Total.total
	}else{
		res.msg='内部错误~'
		res.code=500
	}
	return res
}
exports.SelUserList = SelUserList

// 更新用户信息接口 (洋盘用户的)
exports.UpdUser = async function(body_data) {
	let res = {
		code:200,
		msg:"成功~"
	}
	let {UserInfo,_id,pwd,Nickname,birth,sex,introduce} = body_data
	if (!_id.toString()) {return {msg: "_id必传"}}
	
	let UpdJson = {}
	let celue = ['pwd','Nickname','birth','sex','introduce']
	for(let i in celue){ 
		body_data[celue[i]]  ? UpdJson[celue[i]]= body_data[celue[i]] :"" 
	}
	let result = await db.collection('User').doc(_id).update(UpdJson)
	if(result.requestId){
		res.msg='更新成功~'
		res.data=result.data
	}else{
		res.msg='内部错误~'
		res.code=500
	}
	return res
}

/*	
	删除用户接口 (洋盘用户的)
		1.删除用户 ，
		2.删除oss存储信息，
		3.上传次账号上传的图片信息
*/
exports.DelUser = async function(body_data) {
	let res = {
		code:200,
		msg:"成功~"
	}
	let {UserInfo,_id} = body_data
	if (!_id.toString()) {return {msg: "_id必传"}}
	
	try {
		const result = await db.runTransaction(async transaction => {
			let SelRes = await transaction.collection('User').doc(_id).get()
			if (SelRes.data) {
				try {
					let ossRes = null
					let DelRes = await db.collection('User').doc(_id).remove()		// 删除用户信息
					if(DelRes.deleted>0){
						ossRes = await digui_del(SelRes.data.account+'/')		// 删除oss的数据 （app端的文件数据）
						if(ossRes===200){
							ossRes = await digui_del('uploadImg/'+SelRes.data.account+'/')		// 删除oss的数据（uploadImg下该用户的所有信息）
						}
					}
					console.log(`事务全部成功~`)
					return{
						ossRes,
						DelRes
					}
				} catch (e) {
					await transaction.rollback('oss,remove')
				}
			} else {
				await transaction.rollback('查询User')
			}
		})
	
		return {
			code:200,
			msg:'删除成功~',
			data:{
				ossRes:result.ossRes,
				DelRes:result.DelRes
			}
		}
	} catch (e) {
		console.error(`事务失败`,e)
		return {
			msg:'内部错误~',
			code:500
		}
	}
}

// 递归删除函数 (洋盘用户的)
let digui_del = async (dir)=>{
	let res = {}
	let DelFilePathArr = []
	let DelFolderPathArr = []
	// 递归函数  		先查询给目录下的文件夹（然后递归遍历里面的文件一一删除）
	let SelHasFile = async(dir,type)=>{
		let result = await alioss.FolderList(dir);  // 查询指定oss下所有文件
		let objects = result.objects || [];						// 文件
		let FolderList = result.prefixes ? result.prefixes : []; // 文件夹
			
		if(objects.length>0){ // 塞文件
			for(let [inx,item] of Object.entries(objects)){
				item.type = tools.getFileType(item.name)
				if(inx==0 && item.type=='/') continue
				DelFilePathArr.push(item.name)
			}
		}
		if(FolderList.length>0){  // 塞文件夹
			//*******************这边使用foreach就炸了 async await无法生效*******************//
			for(let i=0,item;item=FolderList[i];i++){
				await SelHasFile(item)
				DelFolderPathArr.push(item)
			}
		}
	}
	
	// 判断前端传的是数组还是字符串
	if(dir instanceof Array){
		for(let i=0,item;item=dir[i];i++){
			await SelHasFile(item)
			tools.getFileType(item) === '/' ?DelFolderPathArr.push(item):""
		}
	}else{ 
		await SelHasFile(dir)
		tools.getFileType(dir) === '/' ?DelFolderPathArr.push(dir):""
	}	
	
	/*
		文件夹排序 必须是从最里层开始排序删除
		
		只是换成对象数组 然后重新排序
	*/
	let newArr = []
	for(let i=0,item;item=DelFolderPathArr[i];i++){
		newArr.push({ len:item.split('/').length , cont:item })
	}
	newArr.sort( (a,b)=> b.len - a.len)
	DelFolderPathArr = []
	for( let i=0,item;item=newArr[i];i++){ DelFolderPathArr.push(item.cont) }
	DelFilePathArr.push.apply(DelFilePathArr,DelFolderPathArr)
	
	
	
	
	
	/*
		@return 
			200 全部删除成功~
			201 部分删除成功~
	*/
	return new Promise(async(resolve,reject)=>{
		// OSS数据删除操作部分
		let successCodeArr = []
		for(let i=0,item;item=DelFilePathArr[i];i++){
			let result = await alioss.deleteFile(item)
			if(result.res.status==204 || result.res.status==200){successCodeArr.push(200)}
		}
		if(successCodeArr.filter(i=>i===200).length === DelFilePathArr.length){
			res.code = 200;
			res.msg='全部删除成功~';
			res.DelList = DelFilePathArr;
			resolve(200)
		}else{
			res.code = 204;
			res.msg='部分删除成功~';
			resolve(201)
		}	
	})
}

